﻿// 2023/3/20: 首个版本
// 2023/9/25: 改为直接输入Icon对象
// 2024/6/24: 基于API3，支持异步
// 2025/2/18: 处理客户端模式未连接的情况

using System;
using System.Collections.Generic;
using System.Linq;
using ASEva;
using ASEva.Samples;
using ASEva.UIEto;
using Eto.Forms;
using Eto.Drawing;

namespace CommonSource
{
    class BusMessageChooser : DialogPanel
    {
        public BusMessageChooser(String originMessageID, Icon icon = null)
        {
            current = originMessageID;

            Icon = icon;
            Title = chinese ? "报文选择" : "Select Bus Message";
            SetFixMode(440, 540, true);

            var mainLayout = this.SetContentAsColumnLayout();
            searchBox = mainLayout.AddControl(new SearchBox()) as SearchBox;
            treeView = mainLayout.AddControl(new SimpleTreeView(), true) as SimpleTreeView;

            Button buttonDelete = null;
            var buttonLayout = mainLayout.AddRowLayout();
            if (current != null) buttonDelete = buttonLayout.AddButton(chinese ? "删除" : "Delete", false, 100);
            buttonLayout.AddSpace();
            buttonSelect = buttonLayout.AddButton(chinese ? "确认" : "OK", false, 100);

            initTreeView();

            searchBox.TextChanged += async delegate
            {
                noAvailables = !rebuildTreeView(await AgencyAsync.GetSignalTree(), searchBox.Text.ToLower(), false);
                if (noAvailables)
                {
                    buttonSelect.Enabled = false;
                    addNoAvailables();
                }
            };

            if (buttonDelete != null)
            {
                buttonDelete.Click += delegate
                {
                    Result = ResultType.Delete;
                    Close();
                };
            }

            buttonSelect.Click += delegate
            {
                Result = ResultType.Select;
                Close();
            };

            treeView.SelectedItemChanged += delegate
            {
                if (noAvailables) return;

                var key = treeView.GetSelectedKey();

                current = null;
                if (key is SignalTreeNode)
                {
                    var nodeType = (key as SignalTreeNode).Type;
                    if (nodeType == SignalTreeNodeType.BusMessage) current = (key as SignalTreeNode).ID;
                }

                buttonSelect.Enabled = current != null;
            };

            treeView.SelectedItemActivated += delegate
            {
                if (buttonSelect.Enabled)
                {
                    Result = ResultType.Select;
                    Close();
                }
            };
        }

        private async void initTreeView()
        {
            searchBox.Enabled = buttonSelect.Enabled = false;

            if (rebuildTreeView(await AgencyAsync.GetSignalTree(), "", true))
            {
                searchBox.Enabled = true;
                buttonSelect.Enabled = current != null;
            }
            else addNoAvailables();
        }

        public enum ResultType
        {
            Cancel = 0,
            Select = 1,
            Delete = 2,
        }

        public ResultType Result { get; set; }

        public String SelectedMessage
        {
            get
            {
                return current == null ? null : current.Clone() as String;
            }
        }

        private bool rebuildTreeView(SignalTreeNode[] tops, String key, bool init)
        {
            if (tops == null) return false;

            var topNodes = new List<SimpleTreeNode>();
            var itemAdded = false;
            bool keyValid = key.Length >= 2;
            object keyToSelect = null;

            foreach (var top in tops)
            {
                if (top.Type != SignalTreeNodeType.BusProtocol) continue;

                var topMatch = keyValid && top.Name.ToLower().Contains(key);

                var topNode = new SimpleTreeNode{ Key = top, Text = top.Name };
                var shouldAddTopNode = !keyValid || topMatch;

                foreach (var middle in top.Children)
                {
                    var middleMatch = keyValid && (middle.ID.ToLower().Contains(key) || middle.Name.ToLower().Contains(key));

                    var middleNode = new SimpleTreeNode{ Key = middle, Text = middle.Name };
                    bool shouldAddMiddleNode = !keyValid || topMatch || middleMatch;

                    if (current != null && middle.ID == current)
                    {
                        middleNode.TextColor = Colors.Green;
                        keyToSelect = middleNode.Key;
                    }
                    else middleNode.TextColor = Colors.Blue;

                    if (shouldAddMiddleNode)
                    {
                        topNode.ChildNodes.Add(middleNode);
                        shouldAddTopNode = true;
                    }
                }

                if (shouldAddTopNode)
                {
                    if (keyValid) topNode.ChildNodesExpanded = true;
                    topNodes.Add(topNode);
                    itemAdded = true;
                }
            }

            treeView.SetModel(topNodes.ToArray(), true);
            if (keyToSelect != null) treeView.SelectItem(keyToSelect);

            return itemAdded;
        }

        private void addNoAvailables()
        {
            var topNode = new SimpleTreeNode{ Key = new object(), Text = chinese ? "(无可用)" : "(No availables)" };
            treeView.SetModel(new SimpleTreeNode[]{ topNode }, false);
        }

        private String current;
        private bool noAvailables;
        private SimpleTreeView treeView;
        private SearchBox searchBox;
        private Button buttonSelect;

        private bool chinese = AgencyLocal.GetAppLanguage() == Language.Chinese;
    }
}
